package cn.pangza.user.websocket;

import cn.pangza.websocket.config.WebSocketServerConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Component
@ServerEndpoint(value = "/user/socket", configurator = WebSocketServerConfig.class)
public class UserWebSocket {

    // 记录连接数
    private static AtomicInteger onlineCount = new AtomicInteger(0);

    // 记录在线人信息
    private static Map<String, UserWebSocket> clinetMap = new ConcurrentHashMap<>();

    // 某个客户端链接 session
    private Session session;

    // 标识当前会话 key
    private String erp = "";

    @OnOpen
    public void onOpen(Session clientSession, EndpointConfig endpointConfig) throws IOException {
        Map<String, Object> userProperties = endpointConfig.getUserProperties();
        String erp = (String) userProperties.get("erp");
        this.erp = erp;
        session = clientSession;
        if(clinetMap.containsKey(erp)) {
            clinetMap.get(this.erp).session.close();
            clinetMap.remove(this.erp);
            onlineCount.decrementAndGet();
        }
        clinetMap.put(this.erp, this);
        onlineCount.incrementAndGet();
        log.info("有人连接了,当前连接数: {}", onlineCount);
        sendMessageTo("连接成功", session);
        sendMessageAll(this.erp + "上线了");
    }

    @OnClose
    public void onClose() throws IOException {
        if(clinetMap.containsKey(erp)) {
            clinetMap.get(erp).session.close();
            clinetMap.remove(erp);
            onlineCount.decrementAndGet();
        }
        log.info("有人断开连接了,当前连接数: {}", onlineCount);

    }

    @OnError
    public void onError(Session session, Throwable throwable) throws IOException {
        log.error("{}, websocket 连接失败, 原因: {}", this.erp, throwable.getMessage(), throwable);
        session.close();
    }

    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        // 心跳机制，避免断开
        if (message.equals("ping")) {
            this.sendMessageTo("pang", session);
        }
        log.info("服务端接收到 {} 发来的消息，消息为: {}", this.erp, message);
    }

    public void sendMessageTo(String message, Session session) throws IOException {
        log.info("服务端给客户端 {} 发送消息 {}", this.erp, message);
        session.getBasicRemote().sendText(message);
    }

    public void sendMessageAll(String message) throws IOException {
        for(Map.Entry<String, UserWebSocket> sessionEntry: clinetMap.entrySet()) {
            String erp = sessionEntry.getKey();
            UserWebSocket webSocket = sessionEntry.getValue();
            Session session = webSocket.session;
            session.getBasicRemote().sendText(message);
        }
    }

}
